package com.css.security.core.authorization;

import com.css.common.core.utils.R;
import com.css.common.security.constant.SecurityConstants;
import com.css.common.security.enums.LoginResponseType;
import com.css.common.security.properties.SecurityProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * CssAccessDeniedHandler
 * 权限认证失败跳转策略
 *
 * @author hanyx
 * @date 2019/04/30
 */
@Component("cssAccessDeniedHandler")
public class CssAccessDeniedHandler extends AccessDeniedHandlerImpl {

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * Handles an access denied failure.
     *
     * @param request               that resulted in an <code>AccessDeniedException</code>
     * @param response              so that the user agent can be advised of the failure
     * @param accessDeniedException that caused the invocation
     * @throws IOException      in the event of an IOException
     * @throws ServletException in the event of a ServletException
     */
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setContentType(SecurityConstants.APPLICATION_JSON_CONTENT_TYPE);
        response.setStatus(HttpStatus.FORBIDDEN.value());
        if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getSignInResponseType())) {
            response.getWriter().write(objectMapper.writeValueAsString(R.buildError("权限不足，请联系管理员!")));
        } else {
            // 如果设置了css.security.browser.accessDeniedUrl，总是跳到设置的地址上
            // 如果没设置，则尝试跳转到登录之前访问的地址上，如果登录前访问地址为空，则跳到网站根路径上
            if (StringUtils.isNotBlank(securityProperties.getBrowser().getAccessDeniedUrl())) {
                super.setErrorPage(securityProperties.getBrowser().getAccessDeniedUrl());
            }
            super.handle(request, response, accessDeniedException);
        }
    }
}
